﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RootBaseFramework
{
    public abstract class RootEntityBase<Tkey> : IBloodLine
       
    {

  

        public long Id { get; set; }

        public long? ParentId { get; set; }

        bool _isNewParentValid;
        public bool IsNewParentValid { get { return _isNewParentValid; } }

        RootEntityBase<long> _Parent;
        public RootEntityBase<long> Parent
        { 
            get
            {
                return _Parent;
            }
            set
            {

                Policy.RootEntiyBase.IsParentValid policy = new Policy.RootEntiyBase.IsParentValid(this);

                if (policy.IsSatisfiedBy(value))
                {
                    _Parent = value;
                    TraceBloodLine();
                    _isNewParentValid = true;
                }
                else
                {
                    _isNewParentValid = false;
                }

               
               
            }
        }

        public virtual  void TraceBloodLine(char delimeter = '`')
    {
                  

        _delimeter = delimeter;
          string bloodline = string.Empty;
          if (Parent != null)
          {
              
            
              bloodline = Parent.BloodLine;
              this.ParentId = Parent.Id;
              bloodline = bloodline  + this.Id.ToString() + delimeter;



          }
          else//root
          {
              bloodline = delimeter + this.Id.ToString() + delimeter;

          }


          BloodLine = bloodline;

         // UpdateBloodLines();
    }

        public abstract void UpdateBloodLines( object MyService );
        //{



        //    var q = GetMyLines(MyRepo,MyUnitOfWork);

            

        //    if (q.Count > 0)
        //    {
        //        foreach (RootEntityBase<long> item in q)
        //                    {
        //                        if(!string.IsNullOrEmpty( OldBloodLine))
        //                        item.BloodLine = item.BloodLine.Replace(OldBloodLine,BloodLine);
        //                    }

        //       var Uow = (RootBaseFramework.Infra.Data.UnitOfWork)MyUnitOfWork;
        //       Uow.Commit();
        //    }

          
            
        //}


        //Domain.IRepository<IBloodLine,long> _myRepo;
        //public Domain.IRepository<IBloodLine, long> MyRepo { get { return _myRepo; } }
        //Infra.Data.UnitOfWork _myUnitOfWork;
        //public Infra.Data.UnitOfWork MyUnitOfWork { get { return _myUnitOfWork; } }


        //public abstract List<Object> GetMyLines(object Repo, object uWork);

        //private List<IBloodLine> GetMyLines(Domain.IRepository<IBloodLine, long> Repo, Infra.Data.UnitOfWork UWork)
        //{
           

        //    if (SetRepository(Repo, UWork))
        //    {

        //        var q = MyRepo.FindAll(p => p.BloodLine.StartsWith(OldBloodLine)).ToList();
        //        return q.ToList();
        //    }
        //    else
        //    {
        //        return new List<IBloodLine>();
        //    }


           
        //    //var q1 = q.Where(p => p.BloodLine.StartsWith(OldBloodLine));
        //    //return q1.Cast<object>().ToList();
        //}


        //private  bool SetRepository(Domain.IRepository<IBloodLine, long> Repo, Infra.Data.UnitOfWork UWork)
        //{
        //    if (Repo == null || UWork == null)
        //    {
        //        return false;
        //    }
        //    else
        //    {
        //        _myUnitOfWork = UWork;
        //        _myRepo = Repo;
        //        return true;
        //    }

        //}
   
        
        string _bloodLine;
    public   string BloodLine
        {
            get
            {
                if (string.IsNullOrEmpty(_bloodLine))
                    _bloodLine = string.Empty; //Delimeter.ToString();
                return _bloodLine;
            }
            set
            {
                _oldBloodLine = BloodLine;
                _bloodLine = value;
            }
        }

    string _oldBloodLine;
    public string OldBloodLine { get { return _oldBloodLine;} }


    private char _delimeter = '`';
    public char Delimeter
    {
        get
        {            
            return _delimeter;
        }
    }
    }

    

    #region ModelConfiguration Sample

  //  class PersonConfiguration
  //: EntityTypeConfiguration<Person>
  //  {

  //      public PersonConfiguration()
  //      {


  //          HasKey(c => c.EntityId)
  //         .Property(c => c.EntityId)
  //         .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);


  //          ToTable("Person");

  //          HasMany(c => c.Children).WithOptional().HasForeignKey(c => c.ParentId).WillCascadeOnDelete(false);


  //      }
  //  }

    #endregion


    public interface IGetTypeInterface
    {
        // Any class that implements IGetTypeInterface must define a method
        // that matches the following signature.
        Type GetTypeOfId();

    }

    public interface IBloodLine
    {
         long Id { get; set; }

         long? ParentId { get; set; }   
         string BloodLine { get; set; }
         char Delimeter { get; }


    }
}
